/**
 * @file         bsc_can_plug.h
 * @brief        CAN服务框架 ———— 插件类
 * @note         组件与用户之间的连接，用户需要构造插件列表向服务组件完成注册
 * @author       Jpz(puzhao.jin@hopechart.com, 靳普诏)
 * @data         2022-8-10
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2022-8-10   <td>1.0                   <td>Jpz             <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */

#ifndef _BSC_CAN_PLUG_H_
#define _BSC_CAN_PLUG_H_

#include "ofc/ofc_types.h"
#include "bsc_can_server/bsc_can_server_if.h"
#include "bsc_can_server/bsc_can_plug_if.h"

#ifdef __cplusplus
extern "C" {
#endif

// ~~~~~~~~~~~~~~~~~~~~~~~ 插件类 ~~~~~~~~~~~~~~~~~~~~~~

enum TBsCanPlugStateTag
{
    kBsCanPlugStateClosed = 0,
    kBsCanPlugStateClosing = 1,
    kBsCanPlugStateOpening = 2,
    kBsCanPlugStateOpened = 3
}; 
typedef enum TBsCanPlugStateTag TBsCanPlugState;


typedef struct TBsCanPlugTag TBsCanPlug;
struct TBsCanPlugTag 
{
    const IBsCanPlugIf *plug_if_;     // 插件接口集 （用户提供具体实现，[const 数组]）
    void *user_param;           // 用户传参 （带入到）
    UInt32 act_tick_;           // 触发时刻
    UInt8 channel_mask;         // 数据通道  （用户提供）
    Bool is_disable;             // 插件禁止标志
    UInt8 state;                // 插件状态
};

// ~~~~~~~~~~~~~~~~~~~~~~ 服务组件调用 ~~~~~~~~~~~~~~~~~~~~~~~~~~

Int32 TBsCanPlugCreate(TBsCanPlug *self, IBsCanServerIf *server_if);
Int32 TBsCanPlugDestroy(TBsCanPlug *self, IBsCanServerIf *server_if);

void TBsCanPlugPushData(TBsCanPlug *self, IBsCanServerIf *server_if, TBsCanData *can_data);
void TBsCanPlugRunOnce(TBsCanPlug *self, IBsCanServerIf *server_if);
void TBsCanPlugRunOnceEx(TBsCanPlug *self, IBsCanServerIf *server_if);

/**
 * 通过建立const插件表代替 BsCanPlugInit
 * 示例：
 * step1 >> 创建插件接口列表
 * const IBsCanPlugIf g_bsc_can_plug_if_def[] = {
 *   {NULL, NULL, TCanServerBsPlugReceive, TCanServerBsPlugScheduler},
 *   {NULL, NULL, TestBsCanPlugReceive0, TestBsCanPlugScheduler0}, 
 *   {NULL, NULL, TestBsCanPlugReceive1, TestBsCanPlugScheduler1}, 
 * };
 * 
 * step2 >> 将插件接口分配给固定的插件对象
 * TBsCanPlug g_bsc_can_normal_plug[] = {
 *   {&g_bsc_can_plug_if_def[0], NULL, 0, 0x1},        // 兼容 406 原始can服务
 *   {&g_bsc_can_plug_if_def[1], NULL, 0, 0x1},
 *   {&g_bsc_can_plug_if_def[2], NULL, 0, 0x1},
 *   {NULL, NULL,0,0}, // 结束标志
 * };
 * 
 * step3 >> 将插件对象表通过 TBsCanServerRegisterPlugTable() 注册到组件
 */


#ifdef __cplusplus
} // extern "C" {
#endif


#endif // #ifndef _BSC_CAN_PLUG_H_

